using System.Reflection.Metadata;
using Eno.Application.Dto;
using Eno.Domain.Entity.App;
using Eno.Domain.Repositories;

namespace Eno.Application.Services;

public class UserService
{
    private readonly IUserRepository<AppUser> _userRep;
    private readonly IUserToRoleRepository _userRole;
    private readonly RoleService _roleService;
    private readonly AppointRemoveService _appointRemoveService;
    private readonly ILogService _logService;

    public UserService(IUserRepository<AppUser> repository, RoleService roleService, IUserToRoleRepository userToRole, AppointRemoveService appointRemoveService, ILogService logService)
    {
        _userRep = repository;
        _roleService = roleService;
        _userRole = userToRole;
        _appointRemoveService = appointRemoveService;
        _logService = logService;
    }


    public async Task<IEnumerable<AppUser>> SelectUser()
    {
        var userList = await _userRep.GetUserAllAsync();
        return userList;
    }


    public async Task<AppUser?> SelectOneAsync(Guid userId)
    {
        return await _userRep.GetUserByIdAsync(userId);
    }

    public async Task<AppUser?> GetUserAccount(string account)
    {
        return await _userRep.GetUserByAccount(account);

    }

    public async Task<int> AddUserAsync(UserDto userDto)
    {
#pragma warning disable CS8604 // Possible null reference argument.
        var role = await _roleService.GetIdByRoleName(userDto.DefaultRole);
#pragma warning restore CS8604 // Possible null reference argument.
        if (role == null)
        {
            await _logService.LogWarningAsync($"注册用户失败，角色不存在: {userDto.DefaultRole}", "UserService", new { userDto.Account, userDto.DefaultRole });
            return 0;
        }
        var rId = role.ID;
        var obj = await _userRep.GetUserByAccount(userDto.Account);
        if (obj != null) return 0;
        var pwdHandle = new PasswordService();
        var hashPwd = pwdHandle.HashPassword(userDto.Password, out string salt);
        var user = new AppUser
        {
            ID = Guid.NewGuid(),
            Account = userDto.Account,
            Password = hashPwd, //* 存储散列密码
            Salt = salt,
            DepartmentID = userDto.DepartmentId,
            Remarks = userDto.Remarks,
            IsDeleted = userDto.IsDeleted,
            IsActived = userDto.IsActived,
            Avatar = userDto.Avatar,
            DisplayName = userDto.DisplayName,
            Email = userDto.Email,
            Phone = userDto.Phone
        };
        await _userRep.AdditionUserAsync(user);
        var result = await _appointRemoveService.AppointUserToRole(rId, user.ID);
        // 写入日志
        await _logService.LogInfoAsync($"注册新用户: {user.Account}", "UserService", new { user.ID, user.Account });

        return result;
    }

    public async Task<int> EditUserAsync(Guid userId, UserDto userDto)
    {
        var pwdHandle = new PasswordService();
        var user = await _userRep.GetUserByIdAsync(userId);
        if (user == null) return 0;
        pwdHandle.HashPassword(userDto.Password, out string hashPwd);
        user.Account = userDto.Account;
        user.Password = hashPwd;
        user.UpdatedAt = DateTime.UtcNow;
        user.IsDeleted = userDto.IsDeleted;
        user.Remarks = userDto.Remarks;
        user.DepartmentID = userDto.DepartmentId;
        user.IsActived = userDto.IsActived;
        return await _userRep.UpdateUserAsync(user);

    }

    public async Task<int> DeleteUserAsync(Guid userId)
    {
        var user = await _userRep.GetUserByIdAsync(userId);
        if (user == null)
        { return 0; }
        var delLinkTab = await _userRole.DeleteUser(userId);
        if (delLinkTab < 0)
        {
            return 0;
        }
        else
        {
            var delSelf = await _userRep.DeleteUserAsync(userId);
            if (delSelf < 0)
            {
                return 0;
            }
            return delSelf;
        }
    }

    public async Task<int> UpdateProfileAsync(string account, UpdateProfileDto dto)
    {
        Console.WriteLine($"[UpdateProfileAsync] account={account}, dto={{DisplayName={dto.DisplayName}, Email={dto.Email}, Phone={dto.Phone}}}");
        var user = await GetUserAccount(account);
        if (user == null)
        {
            Console.WriteLine($"[UpdateProfileAsync] 未找到用户: {account}");
            return 0;
        }
        Console.WriteLine($"[UpdateProfileAsync] user.ID={user.ID}, user.Account={user.Account}");
        user.DisplayName = dto.DisplayName ?? user.DisplayName;
        user.Email = dto.Email ?? user.Email;
        user.Phone = dto.Phone ?? user.Phone;
        user.UpdatedAt = DateTime.UtcNow;
        var result = await _userRep.UpdateUserAsync(user);
        Console.WriteLine($"[UpdateProfileAsync] UpdateUserAsync result={result}");
        return result;
    }

    public async Task<int> UpdateUserAvatarAsync(AppUser user)
    {
        return await _userRep.UpdateUserAsync(user);
    }

    // 获取用户角色名列表
    public async Task<List<string>> GetUserRolesAsync(Guid userId)
    {
        // 直接调用仓储层方法
        return await _userRep.GetUserRolesAsync(userId);
    }


    public async Task<int> ChangePasswordAsync(Guid userId, string oldPassword, string newPassword)
    {
        var user = await _userRep.GetUserByIdAsync(userId);
        if (user == null) return 0;
        var pwdService = new PasswordService();
        var oldHash = pwdService.HashPassword(oldPassword, user.Salt);
        if (user.Password != oldHash) return -1; // 旧密码错误
        var newHash = pwdService.HashPassword(newPassword, out string newSalt);
        user.Password = newHash;
        user.Salt = newSalt;
        user.UpdatedAt = DateTime.UtcNow;
        return await _userRep.UpdateUserAsync(user);
    }
}
